/*
 *@(#)SupportImpl.java 1.0 Feb 1, 2008
 *Copyright Fution Bai
 *
 */
package codebush.service.impl;

import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.PreparedStatementCallback;
import org.springframework.jdbc.core.simple.SimpleJdbcDaoSupport;
import org.springframework.jdbc.support.rowset.SqlRowSet;
import org.springframework.transaction.annotation.Transactional;

import codebush.domain.Users;
import codebush.service.Get;
import codebush.service.Support;
import codebush.service.support.mail.CodebushMailRetriever;
import codebush.service.support.mail.CodebushMailSender;
import codebush.service.support.rowMapper.RowMapperForUsers;
import codebush.util.ContentUtil;

/**
 * 
 * @author Fution Bai
 * @since 1.0
 */
public class SupportImpl extends SimpleJdbcDaoSupport implements Support {

	private CodebushMailRetriever codebushMailRetriever;
	private CodebushMailSender codebushMailSender;
	private Get get;

	/**
	 * annoying setters and getters
	 * 
	 * @return
	 */
	public Get getGet() {
		return get;
	}

	public void setGet(Get get) {
		this.get = get;
	}

	/**
	 * for people to register
	 */
	@SuppressWarnings("unused")
	@Transactional
	public Map<String, Object> signup(String name, String password, String email) {
		Map<String, Object> map = new HashMap<String, Object>();
		if (this.getGet().whetherRegistered(email)) {
			map.put("registerted", false);
			map.put("result", false);
			return map;
		}
		String sql = "insert into users(name,password,email) values('" + name + "','" + ContentUtil.passwordEncryption(password) + "','" + email + "')";
		getJdbcTemplate().execute(sql);
		map.put("result", true);
		sendSignUpConfirmmail: try {
			String[] to = { email };
			Map<String, String> model = new HashMap<String, String>();
			model.put("email", email);
			this.getCodebushMailSender().send("service@codebush.com", to, "谢谢你的注册", "/support/mailTemplate/signup_confirm_mt.ftl", model);
		} catch (RuntimeException e) {
			;
		}
		return map;
	}

	/**
	 * retrieve inbox mails
	 */
	public void mailRetrieve() {
		this.getCodebushMailRetriever().retrieve();
	}

	/**
	 * For password reset when the user forget the password
	 */
	public String passwordReset(String email, String md5text, String password) {

		Map<String, String> model = new HashMap<String, String>();

		if (email != null && md5text == null && password == null) {
			if (!this.getGet().whetherRegistered(email)) {
				return "email_not_registered";
			}
			md5text = ContentUtil.MD5(email + new Date().getTime());
			String sql = "insert into password_reset(email, md5text) values('" + email + "','" + md5text + "')";
			getJdbcTemplate().execute(sql);
			model.put("email", email);
			model.put("md5text", md5text);
			String[] to = { email };
			this.getCodebushMailSender().send("webmaster@codebush.com", to, "codebush password reset", this.getCodebushMailSender().getPasswordResetMailBodyContentTemplateViewName(), model);
			return "email_for_reset_password_sent";
		}

		if (md5text.length() == 32 && password == null) {
			String sql = "select count(*) from password_reset where md5text='" + md5text + "'";
			int exists = getJdbcTemplate().queryForInt(sql);
			if (exists == 1) {
				return "confirmed";
			}
		}

		if (email != null && md5text != null && password != null) {
			alterPassword(password, email);
			return "success";
		}

		return null;
	}

	/**
	 * for the user to sign in the site
	 */
	public Map<String, Object> signin(String email, String password) {
		Map<String, Object> map = new HashMap<String, Object>();
		if (!this.getGet().whetherRegistered(email)) {
			map.put("registered", false);
			return map;
		}
		String sql = "select * from users where email=?";
		Object[] args = { email };
		SqlRowSet srs = getJdbcTemplate().queryForRowSet(sql, args);
		Users users = RowMapperForUsers.getInstance().mapRow(srs);
		if (ContentUtil.passwordEncryption(password).equals(users.getPassword())) {
			map.put("result", true);
			map.put("users", users);
			updateLastViewTime(users.getId());
			return map;
		}
		map.put("result", false);
		return map;
	}

	/**
	 * update the user's last viewed time to now
	 */
	public void updateLastViewTime(int userId) {
		String sql = "update users set last_view_time = CURRENT_TIMESTAMP where id='" + userId + "'";
		getJdbcTemplate().execute(sql);
	}

	public CodebushMailRetriever getCodebushMailRetriever() {
		return codebushMailRetriever;
	}

	public void setCodebushMailRetriever(CodebushMailRetriever codebushMailRetriever) {
		this.codebushMailRetriever = codebushMailRetriever;
	}

	public CodebushMailSender getCodebushMailSender() {
		return codebushMailSender;
	}

	public void setCodebushMailSender(CodebushMailSender codebushMailSender) {
		this.codebushMailSender = codebushMailSender;
	}

	public void insertFeedback(final String title, final String discription, final String email) {
		String sql = "insert into feedback(title, discription, submitter)values(?,?,?)";
		getJdbcTemplate().execute(sql, new PreparedStatementCallback() {
			public Object doInPreparedStatement(PreparedStatement ps) throws SQLException, DataAccessException {
				ps.setString(1, title);
				ps.setString(2, discription);
				ps.setString(3, email);
				ps.execute();
				return null;
			}
		});
	}
	
	/**
	 * alter the user's password
	 */
	public void alterPassword(String newPassword, String email) {
		getJdbcTemplate().execute("update users set password='" + ContentUtil.passwordEncryption(newPassword) + "'where email='" + email + "'");
	}
}
